package tp_imag.service.impl;

import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.io.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Vector;

import ij.ImagePlus;
import ij.io.FileSaver;
import ij.process.BinaryProcessor;
import ij.process.ByteProcessor;
import ij.process.ImageConverter;
import ij.process.ShortProcessor;
import tp_imag.model.ActualImage;


public class BuscarPuntosBackup {

        String nombreArchivo = "prueba";
        String dirArchivo = ".";
	/**
	 * @param args
	 * @throws IOException 
	 */
	public  BufferedImage execute(BufferedImage source) throws IOException {
        BufferedImage imagenPuntos = new BufferedImage(source.getWidth(),source.getHeight(),BufferedImage.TYPE_BYTE_GRAY);
		ByteProcessor bpPuntos = new ByteProcessor(imagenPuntos);
		ByteProcessor bpRecorrido = new ByteProcessor(imagenPuntos);
		
		int arrayImagenPuntos[][] = bpPuntos.getIntArray();
		int arrayRecorrido[][]    = bpRecorrido.getIntArray();

		int arrayImagen[][] 	  = ActualImage.getInstance().getBinarizedBP().getIntArray();

		int tamanoPunto=4;
		int margenPunto = (new Double(Math.ceil(tamanoPunto/2.0))).intValue();
		int xInicio = 0;
		int yInicio = 0;

		int puntos= 0;
		int xPrimero = 0;
		int yPrimero = 0;
		
		boolean primero = true;
		for (int x=xInicio; x<source.getWidth()-tamanoPunto; x++){
			for (int y=yInicio; y<source.getHeight()-tamanoPunto; y++){
					if (analizarPunto(x,y,arrayImagen,tamanoPunto)){
						arrayImagenPuntos[x][y]=255;
						arrayImagenPuntos[x][source.getHeight()-1-tamanoPunto]=255;
						if(primero){
							xPrimero=x;
							yPrimero=y;
							primero=false;
						}
						puntos++;
					}
			}
		}
		
		//Armar Recorrido
		System.out.println("Armando Recorrido...");
		Recorrido recorrido=armarRecorrido(arrayImagenPuntos, arrayRecorrido, xPrimero, yPrimero ,source.getWidth(),source.getHeight());
		
		ImagePlus nueva = new ImagePlus();
		
		bpPuntos.setIntArray(arrayImagenPuntos);
		nueva.setProcessor(nombreArchivo+"_puntos", bpPuntos);
		ImageConverter icNuevo = new ImageConverter(nueva);
		icNuevo.convertToGray8();
		FileSaver fs = new FileSaver(nueva);
		fs.saveAsJpeg(dirArchivo+"/"+nombreArchivo+"_puntos.jpg");
	    System.out.println("Archivo generado: "+dirArchivo+"/"+nombreArchivo+"_puntos.jpg");


	    bpRecorrido.setIntArray(arrayRecorrido);
        ActualImage.getInstance().setVectorizedBP(bpRecorrido);
		nueva.setProcessor(nombreArchivo+"_puntos_recorrido", bpRecorrido);
		icNuevo = new ImageConverter(nueva);
		icNuevo.convertToGray8();
		fs = new FileSaver(nueva);
		fs.saveAsJpeg(dirArchivo+"/"+nombreArchivo+"_puntos_recorrido.jpg");
	    System.out.println("Archivo generado: "+dirArchivo+"/"+nombreArchivo+"_puntos_recorrido.jpg");
	    
	    
	    System.out.println("nro Puntos: "+puntos);
	    
	    /*
	     * Transformar recorrido de puntos
	     */
	    if(recorrido!=null)
	    	transformarRecorrido(recorrido);
        
	    return bpRecorrido.getBufferedImage();
		}

	static Recorrido armarRecorrido(int arrayOrigen[][], int arrayDestino[][],int x, int y, int ancho, int alto){
		
		System.out.println("Metodo armando recorrido");
		Recorrido recorrido = new Recorrido(arrayOrigen, ancho, alto);
		
		
		try {
			recorrido.buscar(new Coordenada( x, y));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Iterator iCoordenada = recorrido.getPuntos().iterator();
		int cuenta =0;
		while (iCoordenada.hasNext() ){
			Coordenada punto = (Coordenada) iCoordenada.next();
			arrayDestino[punto.getX()][punto.getY()] = 255;
			cuenta++;
		}
		System.out.println("CUENTA: "+cuenta);
	
		return recorrido;
	}
	
	static boolean analizarPunto(int xPuntero, int yPuntero, int arrayImagen[][], int tamanoPunto){
		int cuentaBlancos = 0;
		int cuentaNegros  = 0;
		for (int x=xPuntero; x<xPuntero+tamanoPunto; x++){
			for (int y=yPuntero; y<yPuntero+tamanoPunto; y++){
				if (arrayImagen[x][y]== 0)
					cuentaNegros++;
				else
					cuentaBlancos++;
			}
		}
		return Math.abs(cuentaBlancos - cuentaNegros)<3;
	}
	
	public void transformarRecorrido(Recorrido recorrido) throws IOException{

		/* Aca calculo la transformada de fourie sobre los puntos de recorrido
	     * y arma otro array con cada uno de los puntos tranformados
	     * 
	     * Se aplica X(n)=xn+jyn
	     * X(k)=Sum(X(n)Exp(-jPikn/N) 0<=k<=N-1
	     */

		Vector<CoordenadaTransformada> vt = new Vector(300);
		Vector<Coordenada> vr = recorrido.getPuntos();
			
		int MAX=300;						//Cantidad de puntos del vector tranformado
		int N=recorrido.getPuntos().size();	//Cantidad de puntos de recorrido de la imagen
		double sumX=0;						//Suma para cada k
		double sumY=0;						//Suma para cada k
		double PI=Math.PI;
		Coordenada coordenada;
		
		System.out.println("Cantidad ptos recorrido"+N);
		for (int k=0; k<MAX; k++){
			for (int n=0; n<N-1; n++){
				coordenada=vr.get(n);
				sumX+=coordenada.getX()*Math.cos((2*PI*k*n)/N) + 
				      coordenada.getY()*Math.sin((2*PI*k*n)/N);
				sumY+=-coordenada.getX()*Math.sin((2*PI*k*n)/N) + 
			      coordenada.getY()*Math.cos((2*PI*k*n)/N);
			}
			
			CoordenadaTransformada ct=new CoordenadaTransformada(sumX,sumY);
			vt.add(ct);
		}
		
		/*Vector transformado vt
		 * 
		 */
		
		Iterator iCoordenada = vt.iterator();
		while (iCoordenada.hasNext() ){
			CoordenadaTransformada punto = (CoordenadaTransformada) iCoordenada.next();

			System.out.println("Ptos Transformados: "+punto.getX()+"; "+punto.getY());
		}
		System.out.println("Fin ptos transformados");	
		
		/*
		 * Serializar el vector transformado
		 */
		FileOutputStream fout = new FileOutputStream(dirArchivo+"/"+nombreArchivo+"_vt.dat");
		ObjectOutputStream oos = new ObjectOutputStream(fout);

		oos.writeObject((Vector<CoordenadaTransformada>)vt);
                oos.close();
	    
	}
}





